package pl.us.ij.plugins.segmentation.forms;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import ij.ImagePlus;
import pl.us.ij.plugins.segmentation.SwitchImageListener;
import pl.us.ij.plugins.segmentation.commands.threshold.TwoLevelThresholdCommand;
import pl.us.ij.plugins.segmentation.commands.threshold.TwoLevelThresholdCommandParams;
import pl.us.ij.plugins.segmentation.infrastructure.CategoryInfo;
import pl.us.ij.plugins.segmentation.infrastructure.CommandParams;
import pl.us.ij.plugins.segmentation.localization.Localization;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.util.ResourceBundle;

/**
 * Created by IntelliJ IDEA.
 * User: Przemek
 * Date: 2010-05-26
 * Time: 00:20:22
 * To change this template use File | Settings | File Templates.
 */
public class ThresholdsTwoLevelForm extends CategoryInfo implements ChangeListener, SwitchImageListener {
    private JPanel thresholdsPanel;
    private JSlider thresholdsBottomSlider;
    private JSlider thresholdsTopSlider;
    private JButton thresholdButton;
    private JSpinner bottomSpinner;
    private JSpinner topSpinner;
    private JLabel bottomThresholdLabel;
    private JLabel topThresholdLabel;
    private JLabel maxLabel;
    private JLabel minLabel;
    private boolean lockSliderSpinner;

    public ThresholdsTwoLevelForm(IActionHandler actionHandler) {
        actionHandler.setAction(thresholdButton, TwoLevelThresholdCommand.class, getThresholdsParams());

        minLabel.setText("");
        maxLabel.setText("");

        this.lockSliderSpinner = false;

        thresholdsTopSlider.addChangeListener(this);
        thresholdsBottomSlider.addChangeListener(this);
        topSpinner.addChangeListener(this);
        bottomSpinner.addChangeListener(this);

        bottomSpinner.setModel(new SpinnerNumberModel(thresholdsBottomSlider.getValue(), thresholdsBottomSlider.getMinimum(), thresholdsBottomSlider.getMaximum(), 1));
        topSpinner.setModel(new SpinnerNumberModel(thresholdsTopSlider.getValue(), thresholdsTopSlider.getMinimum(), thresholdsTopSlider.getMaximum(), 1));
    }

    @Override
    public String getTitle() {
        return Localization.getString("thresholdsTwoLevelForm.title");
    }

    @Override
    public JPanel getPanel() {
        return thresholdsPanel;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public String getDescription() {
        return null;
    }


    private ICommandParamGather getThresholdsParams() {

        return new ICommandParamGather() {

            public CommandParams getCommandParams() {
                TwoLevelThresholdCommandParams params = new TwoLevelThresholdCommandParams();

                params.setBottomThreshold(thresholdsBottomSlider.getValue());
                params.setTopThreshold(thresholdsTopSlider.getValue());

                return params;
            }
        };
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        if (this.lockSliderSpinner) {
            return;
        }

        if (e.getSource() == topSpinner) {
            thresholdsTopSlider.setValue((Integer) topSpinner.getValue());

            if (thresholdsBottomSlider.getValue() > thresholdsTopSlider.getValue())
                thresholdsBottomSlider.setValue(thresholdsTopSlider.getValue());

        } else if (e.getSource() == bottomSpinner) {
            thresholdsBottomSlider.setValue((Integer) bottomSpinner.getValue());

            if (thresholdsTopSlider.getValue() < thresholdsBottomSlider.getValue())
                thresholdsTopSlider.setValue(thresholdsBottomSlider.getValue());
        } else if (e.getSource() == thresholdsTopSlider) {
            topSpinner.setValue(thresholdsTopSlider.getValue());

            if (thresholdsBottomSlider.getValue() > thresholdsTopSlider.getValue())
                thresholdsBottomSlider.setValue(thresholdsTopSlider.getValue());

        } else if (e.getSource() == thresholdsBottomSlider) {
            bottomSpinner.setValue(thresholdsBottomSlider.getValue());

            if (thresholdsTopSlider.getValue() < thresholdsBottomSlider.getValue())
                thresholdsTopSlider.setValue(thresholdsBottomSlider.getValue());
        }


    }

    @Override
    public void imageActivated(ImagePlus imp) {

        this.lockSliderSpinner = true;

        try {
            ImagePlusInfo impInfo = new ImagePlusInfo(imp);

            int mx = (int) impInfo.getMax();
            int mn = (int) impInfo.getMin();

            Number valueBottom = (int) impInfo.fitRange((float) thresholdsBottomSlider.getValue());
            Number valueTop = (int) impInfo.fitRange((float) thresholdsTopSlider.getValue());

            thresholdsTopSlider.setMinimum(mn);
            thresholdsTopSlider.setMaximum(mx);
            thresholdsTopSlider.setValue(valueTop.intValue());

            thresholdsBottomSlider.setMinimum(mn);
            thresholdsBottomSlider.setMaximum(mx);
            thresholdsBottomSlider.setValue(valueBottom.intValue());

            bottomSpinner.setModel(new SpinnerNumberModel(valueBottom, mn, mx, 1));
            topSpinner.setModel(new SpinnerNumberModel(valueTop, mn, mx, 1));

            minLabel.setText("Min: " + mn);
            maxLabel.setText("Max: " + mx);
        }
        finally {
            this.lockSliderSpinner = false;
        }
    }

    @Override
    public void imageDeactivated(ImagePlus deactivatedImp, ImagePlus imp) {
        if (imp == null) {
            minLabel.setText("");
            maxLabel.setText("");
        }
        else {
            imageActivated(imp);
        }

    }


    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new FormLayout("fill:d:noGrow", "center:d:noGrow"));
        thresholdsPanel = new JPanel();
        thresholdsPanel.setLayout(new FormLayout("fill:207px:noGrow,left:4dlu:noGrow,fill:80px:noGrow", "center:max(d;4px):noGrow,top:4dlu:noGrow,center:d:noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow,top:4dlu:noGrow,center:max(d;4px):noGrow"));
        CellConstraints cc = new CellConstraints();
        panel1.add(thresholdsPanel, cc.xy(1, 1, CellConstraints.DEFAULT, CellConstraints.FILL));
        thresholdsBottomSlider = new JSlider();
        thresholdsBottomSlider.setMaximum(255);
        thresholdsBottomSlider.setPaintLabels(true);
        thresholdsBottomSlider.setPaintTicks(true);
        thresholdsBottomSlider.setPaintTrack(true);
        thresholdsBottomSlider.setSnapToTicks(true);
        thresholdsBottomSlider.setValueIsAdjusting(false);
        thresholdsPanel.add(thresholdsBottomSlider, cc.xy(1, 3, CellConstraints.FILL, CellConstraints.DEFAULT));
        bottomThresholdLabel = new JLabel();
        this.$$$loadLabelText$$$(bottomThresholdLabel, ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("thresholdsTwoLevelForm.bottomThresholdLabel"));
        thresholdsPanel.add(bottomThresholdLabel, cc.xy(1, 1));
        topThresholdLabel = new JLabel();
        this.$$$loadLabelText$$$(topThresholdLabel, ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("thresholdsTwoLevelForm.topThresholdLabel"));
        thresholdsPanel.add(topThresholdLabel, cc.xy(1, 5));
        thresholdsTopSlider = new JSlider();
        thresholdsTopSlider.setMaximum(255);
        thresholdsTopSlider.setPaintLabels(false);
        thresholdsTopSlider.setPaintTicks(false);
        thresholdsTopSlider.setPaintTrack(true);
        thresholdsTopSlider.setSnapToTicks(true);
        thresholdsTopSlider.setValue(100);
        thresholdsPanel.add(thresholdsTopSlider, cc.xy(1, 7, CellConstraints.FILL, CellConstraints.DEFAULT));
        thresholdButton = new JButton();
        this.$$$loadButtonText$$$(thresholdButton, ResourceBundle.getBundle("pl/us/ij/plugins/segmentation/localization/Localization").getString("thresholdsTwoLevelForm.applyLabel"));
        thresholdsPanel.add(thresholdButton, cc.xy(1, 9));
        bottomSpinner = new JSpinner();
        thresholdsPanel.add(bottomSpinner, cc.xy(3, 3, CellConstraints.FILL, CellConstraints.DEFAULT));
        topSpinner = new JSpinner();
        thresholdsPanel.add(topSpinner, cc.xy(3, 7, CellConstraints.FILL, CellConstraints.DEFAULT));
        minLabel = new JLabel();
        minLabel.setText("Min: -9999999");
        thresholdsPanel.add(minLabel, cc.xy(3, 1));
        maxLabel = new JLabel();
        maxLabel.setText("Max: 999999");
        thresholdsPanel.add(maxLabel, cc.xy(3, 5));
        bottomThresholdLabel.setLabelFor(bottomSpinner);
        topThresholdLabel.setLabelFor(topSpinner);
    }

    /**
     * @noinspection ALL
     */
    private void $$$loadLabelText$$$(JLabel component, String text) {
        StringBuffer result = new StringBuffer();
        boolean haveMnemonic = false;
        char mnemonic = '\0';
        int mnemonicIndex = -1;
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) == '&') {
                i++;
                if (i == text.length()) break;
                if (!haveMnemonic && text.charAt(i) != '&') {
                    haveMnemonic = true;
                    mnemonic = text.charAt(i);
                    mnemonicIndex = result.length();
                }
            }
            result.append(text.charAt(i));
        }
        component.setText(result.toString());
        if (haveMnemonic) {
            component.setDisplayedMnemonic(mnemonic);
            component.setDisplayedMnemonicIndex(mnemonicIndex);
        }
    }

    /**
     * @noinspection ALL
     */
    private void $$$loadButtonText$$$(AbstractButton component, String text) {
        StringBuffer result = new StringBuffer();
        boolean haveMnemonic = false;
        char mnemonic = '\0';
        int mnemonicIndex = -1;
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) == '&') {
                i++;
                if (i == text.length()) break;
                if (!haveMnemonic && text.charAt(i) != '&') {
                    haveMnemonic = true;
                    mnemonic = text.charAt(i);
                    mnemonicIndex = result.length();
                }
            }
            result.append(text.charAt(i));
        }
        component.setText(result.toString());
        if (haveMnemonic) {
            component.setMnemonic(mnemonic);
            component.setDisplayedMnemonicIndex(mnemonicIndex);
        }
    }
}
